package lucene.search
{
	
	import flash.errors.IllegalOperationError;
	import flash.utils.describeType;
	import flash.utils.getQualifiedClassName;	
	
	/**
	 * abstract
	 */
	public class Weight
	{
		protected var _queryNorm:Number;
		protected var _value:Number;
		
		public function Weight(self:Weight)
		{
			if (self != this) {
				throw new IllegalOperationError("Can't instantiate an abstract class directly")
			}
			
			//these functions MUST be implemented in subclasses
			var unimplemented:Array = [sumOfSquaredWeights, normalize];
			//get the fully-qualified name the abstract class
			var abstractTypeName:String = getQualifiedClassName(Weight);
			//get a list of all the methods declared by the abstract class
			//if a subclass overrides a function, declaredBy will contain the subclass name
			var selfDescription:XML = describeType(this);
			var methods:XMLList = selfDescription.method.(@declaredBy == abstractTypeName && unimplemented.indexOf(this[@name])>= 0);
			if(methods.length()> 0)
			{
				//we'll only get here if the function is still unimplemented
				var concreteTypeName:String = getQualifiedClassName(this);
				throw new IllegalOperationError("Function " + methods[0].@name + " from abstract class " + abstractTypeName + " has not been implemented by subclass " + concreteTypeName);
			}			
		}
		
		public function getValue():Number
		{
			return this._value;
		}
		
		/**
		 * abstract
		 */
		public function sumOfSquaredWeights():Number { return 0 }
		
		/**
		 * abstract
		 */
		public function normalize(queryNorm:Number):void {}

	}
}